<!DOCTYPE html>
<html lang="en">
<head>
	<title>three.js webgl - WWOBJLoader2</title>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

	<style>
		body {
			font-family: Monospace;
			background-color: #000;
			color: #fff;
			margin: 0 0 0 0;
			padding: 0 0 0 0;
			border: none;
			cursor: default;
		}
		#info {
			color: #fff;
			position: absolute;
			top: 10px;
			width: 100%;
			text-align: center;
			z-index: 100;
			display:block;
		}
		#info a {
			color: #f00;
			font-weight: bold;
			text-decoration: underline;
			cursor: pointer
		}
		#glFullscreen {
			width: 100%;
			height: 100vh;
			min-width: 640px;
			min-height: 360px;
			position: relative;
			overflow: hidden;
			z-index: 0;
		}
		#example {
			width: 100%;
			height: 100%;
			top: 0;
			left: 0;
			background-color: #000000;
		}
		#feedback {
			color: darkorange;
		}
		#dat {
			user-select: none;
			position: absolute;
			left: 0;
			top: 0;
			z-Index: 200;
		}
	</style>

</head>

<body>
<div id="glFullscreen">
	<canvas id="example"></canvas>
</div>
<div id="dat">

</div>
<script src="Detector.js"></script>
<script src="three.js"></script>
<script src="TrackballControls.js"></script>
<script src="dat.gui.min.js"></script>
<script src="OBJLoader.js"></script>
<script>

    'use strict';

    var WWOBJLoader2Example = (function () {
        function WWOBJLoader2Example( elementToBindTo ) {
            this.renderer = null;
            this.canvas = elementToBindTo;
            this.aspectRatio = 1;
            this.recalcAspectRatio();

            this.scene = null;
            this.cameraDefaults = {
                posCamera: new THREE.Vector3( 0.0, 175.0, 500.0 ),
                posCameraTarget: new THREE.Vector3( 0, 0, 0 ),
                near: 0.1,
                far: 10000,
                fov: 45
            };
            this.camera = null;
            this.cameraTarget = this.cameraDefaults.posCameraTarget;

            this.controls = null;

            this.flatShading = false;
            this.doubleSide = false;

            this.cube = null;
            this.pivot = null;
        }

        WWOBJLoader2Example.prototype.initGL = function () {
            this.renderer = new THREE.WebGLRenderer( {
                canvas: this.canvas,
                antialias: true,
                autoClear: true
            } );
            this.renderer.setClearColor( 0x050505 );

            this.scene = new THREE.Scene();

            this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
            this.resetCamera();
            this.controls = new THREE.TrackballControls( this.camera, this.renderer.domElement );

            var ambientLight = new THREE.AmbientLight( 0x404040 );
            var directionalLight1 = new THREE.DirectionalLight( 0xC0C090 );
            var directionalLight2 = new THREE.DirectionalLight( 0xC0C090 );

            directionalLight1.position.set( -100, -50, 100 );
            directionalLight2.position.set( 100, 50, -100 );

            this.scene.add( directionalLight1 );
            this.scene.add( directionalLight2 );
            this.scene.add( ambientLight );

            var helper = new THREE.GridHelper( 1200, 60, 0xFF4444, 0x404040 );
            this.scene.add( helper );

            var geometry = new THREE.BoxGeometry( 10, 10, 10 );
            var material = new THREE.MeshNormalMaterial();
            this.cube = new THREE.Mesh( geometry, material );
            this.cube.position.set( 0, 0, 0 );
            this.scene.add( this.cube );

            this.pivot = new THREE.Object3D();
            this.pivot.name = 'Pivot';
            this.scene.add( this.pivot );
        };

        WWOBJLoader2Example.prototype.useParseSync = function () {
            var scope = this;
            // texture
            var manager = new THREE.LoadingManager();
            manager.onProgress = function ( item, loaded, total ) {
                console.log( item, loaded, total );
            };
            var texture = new THREE.Texture();
            var onProgress = function ( xhr ) {
                if ( xhr.lengthComputable ) {
                    var percentComplete = xhr.loaded / xhr.total * 100;
                    console.log( Math.round(percentComplete, 2) + '% downloaded' );
                }
            };
            var onError = function ( xhr ) {
            };

            var loader = new THREE.ImageLoader( manager );
            loader.load( 'assets/0_0_0.png', function ( image ) {
                texture.image = image;
                texture.needsUpdate = true;
            } );

            // model
            var loader = new THREE.BufferGeometryLoader( manager );
            loader.load( 'assets/0_0_0.geo', function ( bfGeometry ) {
                var material = new THREE.MeshBasicMaterial( { wireframe:false, color: 0xffffff ,map: texture} );
                var mesh = new THREE.Mesh(bfGeometry,material);
//                mesh.position.y = - 95;
                scope.pivot.add(mesh);
            }, onProgress, onError );
        };


        WWOBJLoader2Example.prototype.useParseAsync = function () {
        };

        WWOBJLoader2Example.prototype.useLoadSync = function () {
        };

        WWOBJLoader2Example.prototype.useLoadAsync = function () {
        };

        WWOBJLoader2Example.prototype.useRunSync = function () {
        };

        WWOBJLoader2Example.prototype.useRunAsyncMeshAlter = function () {
        };

        WWOBJLoader2Example.prototype.finalize = function () {
            this._reportProgress( { detail: { text: '' } } );
        };

        WWOBJLoader2Example.prototype._reportProgress = function( event ) {
        };

        WWOBJLoader2Example.prototype.resizeDisplayGL = function () {
            this.controls.handleResize();

            this.recalcAspectRatio();
            this.renderer.setSize( this.canvas.offsetWidth, this.canvas.offsetHeight, false );

            this.updateCamera();
        };

        WWOBJLoader2Example.prototype.recalcAspectRatio = function () {
            this.aspectRatio = ( this.canvas.offsetHeight === 0 ) ? 1 : this.canvas.offsetWidth / this.canvas.offsetHeight;
        };

        WWOBJLoader2Example.prototype.resetCamera = function () {
            this.camera.position.copy( this.cameraDefaults.posCamera );
            this.cameraTarget.copy( this.cameraDefaults.posCameraTarget );

            this.updateCamera();
        };

        WWOBJLoader2Example.prototype.updateCamera = function () {
            this.camera.aspect = this.aspectRatio;
            this.camera.lookAt( this.cameraTarget );
            this.camera.updateProjectionMatrix();
        };

        WWOBJLoader2Example.prototype.render = function () {
            if ( ! this.renderer.autoClear ) this.renderer.clear();

            this.controls.update();

            this.cube.rotation.x += 0.05;
            this.cube.rotation.y += 0.05;

            this.renderer.render( this.scene, this.camera );
        };

        WWOBJLoader2Example.prototype.alterShading = function () {
            var scope = this;
            scope.flatShading = ! scope.flatShading;
            console.log( scope.flatShading ? 'Enabling flat shading' : 'Enabling smooth shading');

            scope.traversalFunction = function ( material ) {
                material.flatShading = scope.flatShading;
                material.needsUpdate = true;
            };
            var scopeTraverse = function ( object3d ) {
                scope.traverseScene( object3d );
            };
            scope.pivot.traverse( scopeTraverse );
        };

        WWOBJLoader2Example.prototype.alterDouble = function () {
            var scope = this;
            scope.doubleSide = ! scope.doubleSide;
            console.log( scope.doubleSide ? 'Enabling DoubleSide materials' : 'Enabling FrontSide materials');

            scope.traversalFunction  = function ( material ) {
                material.side = scope.doubleSide ? THREE.DoubleSide : THREE.FrontSide;
            };

            var scopeTraverse = function ( object3d ) {
                scope.traverseScene( object3d );
            };
            scope.pivot.traverse( scopeTraverse );
        };

        WWOBJLoader2Example.prototype.traverseScene = function ( object3d ) {
            if ( object3d.material instanceof THREE.MultiMaterial ) {

                var materials = object3d.material.materials;
                for ( var name in materials ) {

                    if ( materials.hasOwnProperty( name ) )	this.traversalFunction( materials[ name ] );

                }

            } else if ( object3d.material ) {

                this.traversalFunction( object3d.material );

            }
        };

        return WWOBJLoader2Example;

    })();

    var app = new WWOBJLoader2Example( document.getElementById( 'example' ) );

    var wwObjLoader2Control = {
        flatShading: app.flatShading,
        doubleSide: app.doubleSide
    };

    var menuDiv = document.getElementById( 'dat' );
    var gui = new dat.GUI( {
        autoPlace: false,
        width: 320
    } );
    menuDiv.appendChild( gui.domElement );

    var folderOptions = gui.addFolder( 'WWOBJLoader2 Options' );
    var controlFlat = folderOptions.add( wwObjLoader2Control, 'flatShading' ).name( 'Flat Shading' );
    controlFlat.onChange( function( value ) {
        console.log( 'Setting flatShading to: ' + value );
        app.alterShading();
    });

    var controlDouble = folderOptions.add( wwObjLoader2Control, 'doubleSide' ).name( 'Double Side Materials' );
    controlDouble.onChange( function( value ) {
        console.log( 'Setting doubleSide to: ' + value );
        app.alterDouble();
    });
    folderOptions.open();


    // init three.js example application
    var resizeWindow = function () {
        app.resizeDisplayGL();
    };

    var render = function () {
        requestAnimationFrame( render );
        app.render();
    };
    window.addEventListener( 'resize', resizeWindow, false );

    console.log( 'Starting initialisation phase...' );
    app.initGL();
    app.resizeDisplayGL();

    // kick render loop
    render();


    // Load a file with OBJLoader.parse synchronously
    app.useParseSync();

    // Load a file with OBJLoader.parseAsync asynchronously using a worker
    app.useParseAsync();

    // Load a file with OBJLoader.load synchronously
    app.useLoadSync();

    // Load a file with OBJLoader.load asynchronously
    app.useLoadAsync();

    // Load a file with OBJLoader.run synchronously
    app.useRunSync();

    // Load a file with OBJLoader.run asynchronously and add normals during onMeshAlter
    app.useRunAsyncMeshAlter();

    app.finalize();

</script>
</body>
</html>